next up previous
Next: D xlayerinfo.c Up: Programming X Overlay Windows Previous: B XLayerUtil.c

C layerdemo.c

/* compile: cc -o layerdemo layerdemo.c XLayerUtil.c -lX11 -lm */

/* Tested on Silicon Graphics IRIX 4.0 and IRIX 5.0 workstations and
 * Hewlett-Packard workstations with CRX24 and CRX48Z graphics hardware.
 */

#include <stdio.h>
#include <math.h>
#include "XLayerUtil.h"

#define SIZE 400 /* width and height of window */

Display *dpy;
Window root, win, overlay;
Colormap cmap;
Visual *defaultVisual;
int screen, black, white, red, nVisuals, i, status;
GC normalGC, overlayGC;
XEvent event;
XLayerVisualInfo template;
XLayerVisualInfo *otherLayerInfo, *defaultLayerInfo;
XSetWindowAttributes winattrs;
XGCValues gcvals;
XColor color, exact;
int x = 0, y = SIZE/2;

redrawNormalPlanes()
{
   /* draw a black 43 legged octopus */
   for(i=0; i<43; i++)
      XDrawLine(dpy, win, normalGC, SIZE/2, SIZE/2,
         (int) (cos(i * 0.15) * (SIZE/2-5)) + SIZE/2,
         (int) (sin(i * 0.15) * (SIZE/2-12)) + SIZE/2);
}

#define MESSAGE1 "This text is in the"
#define MESSAGE2 "OVERLAY PLANES"

redrawOverlayPlanes()
{
   XDrawString(dpy, overlay, overlayGC, x, y, MESSAGE1, sizeof(MESSAGE1)-1);
   XDrawString(dpy, overlay, overlayGC, x, y + 15, MESSAGE2, sizeof(MESSAGE2)-1);
}

fatalError(message)
char *message;
{
   fprintf(stderr, "layerdemo: %s\n", message);
   exit(1);
}

main(argc, argv)
int argc;
char *argv[];
{
   dpy = XOpenDisplay(NULL);
   if(dpy == NULL)
      fatalError("cannot open display");
   screen = DefaultScreen(dpy);
   root = RootWindow(dpy, screen);
   defaultVisual = DefaultVisual(dpy, screen);
   /* find layer of default visual */
   template.vinfo.visualid = defaultVisual->visualid;
   defaultLayerInfo = XGetLayerVisualInfo(dpy, VisualIDMask, &template, &nVisuals);
   /* look for visual in layer "above" default visual with transparent pixel */
   template.layer = defaultLayerInfo->layer + 1;
   template.vinfo.screen = screen;
   template.type = TransparentPixel;
   otherLayerInfo = XGetLayerVisualInfo(dpy,
      VisualScreenMask|VisualLayerMask|VisualTransparentType, &template, &nVisuals);
   if(otherLayerInfo == NULL) {
      /* make sure default visual has transparent pixel */
      if(defaultLayerInfo->type == None)
         fatalError("unable to find expected layer visuals");
      /* visual not found "above" default visual, try looking "below" */
      template.layer = defaultLayerInfo->layer - 1;
      template.vinfo.screen = screen;
      otherLayerInfo = XGetLayerVisualInfo(dpy,
         VisualScreenMask|VisualLayerMask, &template, &nVisuals);
      if(otherLayerInfo == NULL)
         fatalError("unable to find layer below default visual");
      /* XCreateColormap uses AllocNone for 2 reasons:
       * 1) haven't determined class of visual, visual could have static colormap
       * and more importantly
       * 2) transparent pixel might make AllocAll impossible.
       */
      cmap = XCreateColormap(dpy, root, otherLayerInfo->vinfo.visual, AllocNone);
      /* not default colormap, must find our own black and white */
      status = XAllocNamedColor(dpy, cmap, "black", &color, &exact);
      if(status == 0)
         fatalError("could not allocate black");
      black = color.pixel;
      status = XAllocNamedColor(dpy, cmap, "white", &color, &exact);
      if(status == 0)
         fatalError("could not allocate white");
      white = color.pixel;
      winattrs.background_pixel = white;
      winattrs.border_pixel = black;
      winattrs.colormap = cmap;
      win = XCreateWindow(dpy, root, 10, 10, SIZE, SIZE, 0, otherLayerInfo->vinfo.depth,
         InputOutput, otherLayerInfo->vinfo.visual,
         CWBackPixel|CWBorderPixel|CWColormap, &winattrs);
      status = XAllocNamedColor(dpy, DefaultColormap(dpy, screen),
         "red", &color, &exact);
      if(status == 0)
         fatalError("could not allocate red");
      winattrs.background_pixel = defaultLayerInfo->value;
      winattrs.border_pixel = 0;
      winattrs.colormap = DefaultColormap(dpy, screen);
      overlay = XCreateWindow(dpy, win, 0, 0, SIZE, SIZE, 0, DefaultDepth(dpy, screen),
         InputOutput, defaultVisual, CWBackPixel|CWBorderPixel|CWColormap, &winattrs);
   } else {
      /* create lower window using default visual */
      black = BlackPixel(dpy, screen);
      white = WhitePixel(dpy, screen);
      win = XCreateSimpleWindow(dpy, root, 10, 10, SIZE, SIZE, 1, black, white);
      /* see note above about AllocNone */
      cmap = XCreateColormap(dpy, root, otherLayerInfo->vinfo.visual, AllocNone);
      status = XAllocNamedColor(dpy, cmap, "red", &color, &exact);
      if(status == 0)
         fatalError("could not allocate red");
      red = color.pixel;
      winattrs.background_pixel = otherLayerInfo->value; /* use transparent pixel */
      winattrs.border_pixel = 0; /* no border but still necessary to avoid BadMatch */
      winattrs.colormap = cmap;
      overlay = XCreateWindow(dpy, win, 0, 0, SIZE, SIZE, 0, otherLayerInfo->vinfo.depth,
         InputOutput, otherLayerInfo->vinfo.visual,
         CWBackPixel|CWBorderPixel|CWColormap, &winattrs);
   }
   XSelectInput(dpy, win, ExposureMask);
   XSelectInput(dpy, overlay, ExposureMask|ButtonPressMask);
   XSetWMColormapWindows(dpy, win, &overlay, 1);
   gcvals.foreground = black;
   gcvals.line_width = 8;
   gcvals.cap_style = CapRound;
   normalGC = XCreateGC(dpy, win, GCForeground|GCLineWidth|GCCapStyle, &gcvals);
   gcvals.foreground = red;
   overlayGC = XCreateGC(dpy, overlay, GCForeground, &gcvals);
   XMapSubwindows(dpy, win);
   XMapWindow(dpy, win);
   while(1) {
      XNextEvent(dpy, &event);
      switch(event.type) {
      case Expose:
         if(event.xexpose.window == win)
            redrawNormalPlanes();
         else
            redrawOverlayPlanes();
         break;
      case ButtonPress:
         x = random() % SIZE/2;
         y = random() % SIZE;
         XClearWindow(dpy, overlay);
         redrawOverlayPlanes();
         break;
      }
   }
}



next up previous
Next: D xlayerinfo.c Up: Programming X Overlay Windows Previous: B XLayerUtil.c



Mark Kilgard
Sun Jan 7 19:28:30 PST 1996